import io
from datetime import timedelta

from aiogram import Bot, Dispatcher, F
from aiogram.filters import Text
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import any_state
from aiogram.types import Message, ReplyKeyboardRemove
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import sessionmaker

from app.bot.keyboards.reply import user_keyboard
from app.bot.states.states import IdAccounts
from app.bot.utils.date_time import get_date_time
from app.bot.utils.logger import log
from app.bot.utils.scheduler import jobs
from app.database.functions.account import add_account_id
from app.database.functions.stats import update_stats, update_user_stats


async def start_id_accounts(message: Message, state: FSMContext) -> None:
    """
    Добавление аккаунтов по id
    """

    await message.answer(
        "Введите id аккаунтов каждый с новой строки. Вы также можете отправить мне txt файл с аккаунтами",
        reply_markup=ReplyKeyboardRemove(),
    )
    await message.answer("Отправьте /cancel, чтобы вернуться в главное меню")
    await state.set_state(IdAccounts.waiting_accounts)


async def add_accounts(
    message: Message,
    bot: Bot,
    session: AsyncSession,
    session_factory: sessionmaker,
    scheduler: AsyncIOScheduler,
    state: FSMContext,
) -> None:
    if message.document:
        if ".txt" not in message.document.file_name:
            await message.answer("Вы прислали не txt файл")
            await state.set_state(IdAccounts.waiting_accounts)
            return
        else:
            file = io.BytesIO()
            await bot.download(message.document, destination=file)
            file_text = [line.decode().strip() for line in file.readlines()]
            id_accounts = [
                account.strip() for account in file_text if account.isdigit()
            ]
    elif message.text:
        id_accounts = [
            account.strip() for account in message.text.split("\n") if account.isdigit()
        ]
    else:
        await message.answer("Вы не прислали файл или текстовый список аккаунтов")
        await state.set_state(IdAccounts.waiting_accounts)
        return

    if len(id_accounts) > 1:
        await message.answer(
            f"Взял в работу аккаунтов: {len(id_accounts)}", reply_markup=user_keyboard()
        )
        for account in id_accounts:
            await add_account_id(session, message.from_user.id, int(account))
    elif len(id_accounts) > 0:
        await add_account_id(session, message.from_user.id, int(id_accounts[0]))
        await message.answer("Аккаунт добавлен в работу", reply_markup=user_keyboard())
    else:
        await message.answer(
            "Ни один из аккаунтов не попал в работу, исправьте ошибки и загрузите их снова"
        )
        await state.set_state(IdAccounts.waiting_accounts)
        return

    time_limit = get_date_time() + timedelta(days=5)
    scheduler.add_job(
        jobs.check_accounts,
        "interval",
        name="Accounts by id",
        seconds=30,
        args=(
            bot,
            session_factory,
            scheduler,
            message.from_user.id,
            id_accounts,
            time_limit,
        ),
    )
    log.info(f"Добавлена задача id accounts для пользователя {message.from_user.id}")
    await update_stats(
        session,
        accounts=len(id_accounts),
    )
    await update_user_stats(
        session,
        message.from_user.id,
        accounts_added=len(id_accounts),
    )
    await state.clear()


def register_id_accounts_handlers(dp: Dispatcher):
    dp.message.register(
        start_id_accounts,
        Text(text="⚙️ Чекер аккаунтов по ID", ignore_case=True),
        any_state,
    )
    dp.message.register(
        add_accounts,
        IdAccounts.waiting_accounts,
        F.content_type.in_(["text", "document"]),
    )
